home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Environments / Clean 1.2.4 / IOInterface / menuDevice.icl < prev    next >
Encoding:
Modula Implementation  |  1997-04-24  |  15.3 KB  |  408 lines  |  [TEXT/3PRM]

  1. implementation module menuDevice;
  2.  
  3.  
  4. import StdClass;
  5. import    StdBool, StdChar, StdInt, StdMisc, StdString;
  6. import    desk, windows;
  7. import    menuInternal, commonDef;
  8. from    deltaMenu    import SelectMenuRadioItem;
  9. from    dialogAbout    import OpenAboutDialog;
  10.  
  11.  
  12. MenuDeviceError :: String String -> .x;
  13. MenuDeviceError f error = Error f "menuDevice" error;
  14.  
  15.  
  16. MenuFunctions :: DeviceFunctions s;
  17. MenuFunctions = (    ShowMenu,
  18.                         OpenMenu,
  19.                             MenuIO,
  20.                         CloseMenu,
  21.                     HideMenu
  22.                 );
  23.  
  24.  
  25. ShowMenu :: !(IOState s) -> IOState s;
  26. ShowMenu ioState
  27.     =    IOStateSetToolbox (DrawMenuBar (SetMenuSystem menus tb)) ioState2;
  28.     where {
  29.         (menus,    ioState1)    = IOStateGetDevice  ioState MenuDevice;
  30.         (tb,    ioState2)    = IOStateGetToolbox ioState1;
  31.     };
  32.  
  33. CloseMenu    :: !(IOState s) -> IOState s;
  34. CloseMenu ioState
  35.     =    IOStateRemoveDevice (IOStateSetToolbox tb1 ioState2) MenuDevice;
  36.     where {
  37.         (menus,    ioState1)    = IOStateGetDevice  ioState MenuDevice;
  38.         (tb,    ioState2)    = IOStateGetToolbox ioState1;
  39.         tb1                    = DisposeMenuSystemState menus tb;
  40.     };
  41.  
  42. HideMenu :: !(IOState s) -> IOState s;
  43. HideMenu ioState
  44.     =    IOStateSetDevice (IOStateSetToolbox tb2 ioState2) menus1;
  45.     where {
  46.         (menus,    ioState1)    = IOStateGetDevice  ioState MenuDevice;
  47.         (tb,    ioState2)    = IOStateGetToolbox ioState1;
  48.         (menus1, tb1)        = GetMenuSystem menus tb;
  49.         tb2                    = DrawMenuBar (ClearMenuBar tb1);
  50.     };
  51.  
  52.  
  53. //    Opening menu's:
  54.  
  55. OpenMenu :: !(DeviceSystem s (IOState s)) !(IOState s) -> IOState s;
  56. OpenMenu (MenuSystem mDefs) ioState
  57.     =    IOStateSetDevice (IOStateSetToolbox (DrawMenuBar tb3) ioState1) menuSystem;
  58.     where {
  59.         (menuSystem,    tb3)    = GetMenuSystem (MenuSystemState (m_and_hs, cuts, 0, SystemAble)) tb2;
  60.         (m_and_hs, cuts,tb2)    = CreateApple_and_Handles (ProperRadioMenuItems mDefs) tb1;
  61.         tb1                        = ClearMenuBar tb;
  62.         (tb, ioState1)            = IOStateGetToolbox ioState;
  63.     };
  64. OpenMenu _ _
  65.     =    MenuDeviceError "OpenMenu" "argument is no MenuSystem";
  66.  
  67. CreateApple_and_Handles    :: ![MenuDef s (IOState s)] !Toolbox -> (![MenuHandle s], ![Char], !Toolbox);
  68. CreateApple_and_Handles [] tb
  69.     =    ([appleMenu, emptyMenu], [], tb2);
  70.     where {
  71.         (appleMenu, tb1) = AppleMenu tb;
  72.         (emptyMenu, tb2) = EmptyMenuHandle MacPullDownStartId tb1;
  73.     };
  74. CreateApple_and_Handles mDefs tb
  75.     =    CreateHandles [appleMenu] mDefs MacPullDownStartId MacSubMenuStartId [] tb1;
  76.     where {
  77.         (appleMenu, tb1) = AppleMenu tb;
  78.     };
  79.  
  80. CreateHandles :: ![MenuHandle s] ![MenuDef s (IOState s)] !MenuId !MenuId ![Char] !Toolbox
  81.     ->    (![MenuHandle s], ![Char], !Toolbox);
  82. CreateHandles m_and_hs [mDef=: PullDownMenu id s able items : mDefs] pId sId keys tb
  83.     =    CreateHandles (Append m_and_hs menuH`) mDefs pId` sId` keys` tb3;
  84.     where {
  85.         (menuH,                        tb1)= NewMenuHandle mDef pId tb;
  86.         (iNr, menuH`, sId`, keys`,    tb2)= Append_menu_items 1 menuH items sId keys tb1;
  87.         tb3                                = Insert_menu menuH` tb2;
  88.         pId`                            = IncrPullDownMenuId pId;
  89.     };
  90. CreateHandles m_and_hs _ _ _ keys tb = (m_and_hs, keys, tb);
  91.  
  92. Append_menu_items :: !Int !(MenuHandle s) ![MenuElement s (IOState s)] !MenuId ![Char] !Toolbox
  93.     ->    (!Int, !MenuHandle s, !MenuId, ![Char], !Toolbox);
  94. Append_menu_items iNr menuH [subMenu=:SubMenuItem id t s subItems : menuItems] sId keys tb
  95.     =    Append_menu_items (inc iNr) menuH` menuItems sId` keys` tb4;
  96.     where {
  97.         (submenuH, tb1)    = NewMenuElementHandle subMenu sId tb;
  98.         (iNr`, submenuH`, sId`, keys`, tb2)
  99.                         = Append_menu_items 1 submenuH subItems (IncrSubMenuId sId) keys tb1;
  100.         tb3                = Insert_menu submenuH` tb2;
  101.         (menuH`, tb4)    = Append_menu iNr menuH macItem submenuH` tb3;
  102.         macItem            = MenuElementToMacElement (SubMenuItem sId t s subItems);
  103.     };
  104. Append_menu_items iNr menuH [item=:MenuRadioItems id items : menuItems] sId keys tb
  105.     =    Append_menu_items iNr` menuH`` menuItems sId keys` tb3;
  106.     where {
  107.         (radioH, tb1)    = NewMenuElementHandle item 0 tb;
  108.         (iNr`, menuH`, radioH`, keys`, tb2)
  109.                         = Append_radio_items iNr menuH radioH id items keys tb1;
  110.         (menuH``, tb3)    = Append_menu iNr menuH` macItem radioH` tb2;
  111.         macItem            = MenuElementToMacElement item;
  112.     };
  113. Append_menu_items iNr menuH [item=:MenuItemGroup id groupItems : menuItems] sId keys tb
  114.     =    Append_menu_items iNr` menuH`` menuItems sId` keys` tb3;
  115.     where {
  116.         (itemH, tb1)    = NewMenuElementHandle item 0 tb;
  117.         (iNr`, menuH`, itemH`, sId`, keys`, tb2)
  118.                         = Append_group_items iNr menuH itemH groupItems sId keys tb1;
  119.         (menuH``, tb3)    = Append_menu iNr menuH` macItem itemH` tb2;
  120.         macItem            = MenuElementToMacElement item;
  121.     };
  122. Append_menu_items iNr menuH [item : menuItems] sId keys tb
  123.     =    Append_menu_items (inc iNr) menuH` menuItems sId keys` tb2;
  124.     where {
  125.         (itemH,    tb1)    = NewMenuElementHandle item 0 tb;
  126.         (menuH`,tb2)    = Append_menu iNr menuH macItem itemH tb1;
  127.         macItem            = MenuElementToMacElement item`;
  128.         (item`,    keys`)    = CheckShortcutKey item keys;
  129.     };
  130. Append_menu_items iNr menuH _ sId keys tb = (iNr, menuH, sId, keys, tb);
  131.  
  132. Append_group_items ::    !Int !(MenuHandle s) !(MenuHandle s) ![MenuElement s (IOState s)]
  133.                         !MenuId ![Char] !Toolbox
  134.     ->    (!Int, !MenuHandle s, !MenuHandle s, !MenuId, ![Char], !Toolbox);
  135. Append_group_items iNr m_and_h (MenuItemGroupHandle id []) groupItems sId keys tb
  136.     =    (iNr1, m_and_h2, MenuItemGroupHandle id itemGroupHs, sId1, keys1, tb1);
  137.     where {
  138.         (itemGroupHs, m_and_h2)                = SplitMenuHandle m_and_h1 (NrItems m_and_h);
  139.         (iNr1, m_and_h1, sId1, keys1, tb1)    = Append_menu_items iNr m_and_h groupItems sId keys tb;
  140.     };
  141.  
  142. Append_radio_items ::    !Int !(MenuHandle s) !(MenuHandle s) !MenuItemId
  143.                         ![RadioElement s (IOState s)] ![Char] !Toolbox
  144.     ->    (!Int, !MenuHandle s, !MenuHandle s, ![Char], !Toolbox);
  145. Append_radio_items iNr m_and_h (MenuRadioItemsHandle []) theId radioItems keys tb
  146.     =    (iNr1, m_and_h2, MenuRadioItemsHandle checkItemHs, keys1, tb1);
  147.     where {
  148.         (checkItemHs, m_and_h2)                = SplitMenuHandle m_and_h1 (NrItems m_and_h);
  149.         (iNr1, m_and_h1, dummy, keys1, tb1)    = Append_menu_items iNr m_and_h radioItems1 0 keys tb;
  150.         radioItems1                            = RadioToCheckItems theId radioItems;
  151.     };
  152.  
  153. Append_menu    :: !Int !(MenuHandle s) (!String,!String) !(MenuHandle s) !Toolbox -> (!MenuHandle s,!Toolbox);
  154. Append_menu iNr (PullDownHandle menu id macId able items) (title, macStr) itemH tb
  155. |    macStr == ""    = (menuH, tb );
  156.                     = (menuH, tb2);
  157.     where {
  158.         menuH    = PullDownHandle menu id macId able (Append items itemH);
  159.         tb1        = AppendMenu menu macStr tb;
  160.         tb2        = SetItem menu iNr title tb1;
  161.     };
  162. Append_menu iNr (SubMenuItemHandle menu id macId items) (title, macStr) itemH tb
  163. |    macStr == ""    = (menuH, tb );
  164.                     = (menuH, tb2);
  165.     where {
  166.         menuH    = SubMenuItemHandle menu id macId (Append items itemH);
  167.         tb1        = AppendMenu menu macStr tb;
  168.         tb2        = SetItem menu iNr title tb1;
  169.     };
  170.  
  171. NrItems    :: !(MenuHandle s) -> Int;
  172. NrItems (PullDownHandle        _ _ _ _ items)    = Length_new items;
  173. NrItems (SubMenuItemHandle    _ _ _    items)    = Length_new items;
  174. NrItems _                                    = 0;
  175.  
  176. MenuElementToMacElement    :: !(MenuElement s (IOState s)) -> (!String, !String);
  177. MenuElementToMacElement (CheckMenuItem id t NoKey able mark f)
  178. |    Checked mark && Enabled able        = (CheckItemTitle t, s +++ check);
  179. |    Checked mark                        = (CheckItemTitle t, s +++ disable +++ check);
  180. |    Enabled able                        = (CheckItemTitle t, s);
  181.                                         = (CheckItemTitle t, s +++ disable);
  182.     where {
  183.         s      = "D";
  184.         disable= "(";
  185.         check  = "!" +++ toString (toChar 18);
  186.     };
  187. MenuElementToMacElement (CheckMenuItem id t (Key key) able mark f)
  188. |    not (Checked mark)    && Enabled able    = (CheckItemTitle t, s +++ shortcut);
  189. |    Checked mark        && Enabled able    = (CheckItemTitle t, s +++ check   +++ shortcut);
  190. |    not (Checked mark)                    = (CheckItemTitle t, s +++ disable +++ shortcut);
  191.                                         = (CheckItemTitle t, s +++ disable +++ check +++ shortcut);
  192.     where {
  193.         s        = "D";
  194.         shortcut= KeyToShortcut key;
  195.         disable = "(";
  196.         check    = "!" +++ toString (toChar 18);
  197.     };
  198. MenuElementToMacElement (MenuItem id t NoKey able f)
  199. |    Enabled able                        = (CheckItemTitle t, "D");
  200.                                         = (CheckItemTitle t, "D(");
  201. MenuElementToMacElement (MenuItem id t (Key key) able f)
  202. |    Enabled able                        = (CheckItemTitle t, "D"  +++ shortcut);
  203.                                         = (CheckItemTitle t, "D(" +++ shortcut);
  204.     where {
  205.         shortcut = KeyToShortcut key;
  206.     };
  207. MenuElementToMacElement (SubMenuItem id t s items)
  208. |    Enabled s                            = (CheckItemTitle t, submenu_and_id +++ "D");
  209.                                         = (CheckItemTitle t, submenu_and_id +++ "D(");
  210.     where {
  211.         submenu_and_id    = submenu +++ menu_id;
  212.         submenu            = "/" +++  toString (toChar 27);        // /$1B signifies this item as a SubMenu.
  213.         menu_id            = "!" +++  toString (toChar id);        // !id = the menu defining the SubMenu.
  214.     };
  215. MenuElementToMacElement MenuSeparator = ("-", "-(");
  216. MenuElementToMacElement groupOrRadios = ("",  "");
  217.  
  218. KeyToShortcut :: !Char -> String;
  219. KeyToShortcut c
  220. |    c >= 'a' && c <= 'z'    = "/" +++ toString (toChar (toInt 'A' + (toInt c - toInt 'a')));
  221.                             = "/" +++ toString c;
  222.  
  223. CheckShortcutKey :: !(MenuElement s (IOState s)) ![Char] -> (!MenuElement s (IOState s), ![Char]);
  224. CheckShortcutKey item=:(MenuItem id t (Key c) s f) cs
  225. |    ContainsChar cs c        = (MenuItem id t NoKey s f, cs);
  226.                             = (item, [c : cs]);
  227. CheckShortcutKey item=:(CheckMenuItem id t (Key c) s m f) cs
  228. |    ContainsChar cs c        = (CheckMenuItem id t NoKey s m f, cs);
  229.                             = (item, [c : cs]);
  230. CheckShortcutKey item cs    = (item, cs);
  231.  
  232.  
  233. RadioToCheckItems :: !MenuItemId ![RadioElement s (IOState s)] -> [MenuElement s (IOState s)];
  234. RadioToCheckItems theId [MenuRadioItem id t c s f : items]
  235.     =     [CheckMenuItem id t c s (RadioMark id theId) f : RadioToCheckItems theId items];
  236. RadioToCheckItems theId items =  []; 
  237.  
  238. RadioMark :: !MenuItemId !MenuItemId -> MarkState;
  239. RadioMark id1 id2
  240. |    id1 == id2    = Mark;
  241.                 = NoMark;
  242.  
  243.  
  244. /*    Creation of correct internal menu numbers only.
  245.     Note:    MacSubMenuEndId is 234 rather than 235 because the dialogs
  246.             use 235 for generating pop up dialog items.
  247. */
  248.  
  249. MacPullDownStartId    :== 1;
  250. MacPullDownEndId    :== 16;
  251. MacSubMenuStartId    :== 17;
  252. MacSubMenuEndId        :== 234;
  253.  
  254. IncrPullDownMenuId :: !MenuId -> MenuId;
  255. IncrPullDownMenuId id
  256. |    id < MacPullDownEndId    = inc id;
  257.                             = MenuDeviceError    "Creating menus"
  258.                                                 "To many PullDownMenus in one MenuSystem";
  259.  
  260. IncrSubMenuId :: !MenuId -> MenuId;
  261. IncrSubMenuId id
  262. |    id < MacSubMenuEndId    = inc id;
  263.                             = MenuDeviceError    "Creating menus"
  264.                                                 "To many SubMenus in one MenuSystem";
  265.  
  266.     
  267. //    Ensure proper marking when a MenuRadioItem is selected:
  268.  
  269. ProperRadioMenuItems :: ![MenuDef s (IOState s)] -> [MenuDef s (IOState s)];
  270. ProperRadioMenuItems [PullDownMenu id s able items : menus]
  271.     =     [PullDownMenu id s able (MenuProperRadioItems items) : ProperRadioMenuItems menus];
  272. ProperRadioMenuItems menus = menus;
  273.  
  274. MenuProperRadioItems :: ![MenuElement s (IOState s)] -> [MenuElement s (IOState s)];
  275. MenuProperRadioItems [MenuRadioItems id radioItems : menuItems]
  276.     =     [MenuRadioItems id (ProperRadioItems radioItems id) : MenuProperRadioItems menuItems];
  277. MenuProperRadioItems [SubMenuItem id t s subItems : menuItems]
  278.     =     [SubMenuItem id t s (MenuProperRadioItems subItems) : MenuProperRadioItems menuItems];
  279. MenuProperRadioItems [MenuItemGroup id groupItems  : menuItems]
  280.     =     [MenuItemGroup id (MenuProperRadioItems groupItems) : MenuProperRadioItems menuItems];
  281. MenuProperRadioItems [item : menuItems]
  282.     =     [item : MenuProperRadioItems menuItems];
  283. MenuProperRadioItems menuItems = menuItems;
  284.  
  285. ProperRadioItems :: ![RadioElement s (IOState s)] !MenuItemId -> [RadioElement s (IOState s)];
  286. ProperRadioItems [MenuRadioItem id s key able f : radioItems] theId
  287.     =     [MenuRadioItem id s key able (MenuRadioFunction id f) : ProperRadioItems radioItems theId];
  288. ProperRadioItems radioItems theId =  radioItems;
  289.  
  290. MenuRadioFunction :: !MenuItemId !(MenuFunction *s (IOState *s)) !*s !(IOState *s) -> (!*s, !IOState *s);
  291. MenuRadioFunction theId f s ioState = f s (SelectMenuRadioItem theId ioState);
  292.  
  293. //    Doing menu I/O:
  294.  
  295. ::    TraceResult    =    NoMenuEvent
  296.                 |    DeskEvent
  297.                 |    MenuEvent Int Int
  298.                 |    AboutEvent;
  299.  
  300. MenuIO :: !Event !*s !(IOState *s) -> (!Bool, !*s, !IOState *s);
  301. MenuIO event s ioState
  302.     =    MenuIO` menuTrace menus s (IOStateSetToolbox tb1 ioState2);
  303.     where {
  304.         (menus,        ioState1)    = IOStateGetDevice    ioState MenuDevice;
  305.         (tb,        ioState2)    = IOStateGetToolbox    ioState1;
  306.         (menuTrace, tb1)        = MenuTrace event menus tb;
  307.     };
  308.  
  309. MenuIO` :: !TraceResult !(DeviceSystemState *s) !*s !(IOState *s) -> (!Bool, !*s, !IOState *s);
  310. MenuIO` (MenuEvent h v) menus s ioState
  311. |    found    = (True, s1, ioState1);
  312.             = (True, s,  ioState );
  313.     where {
  314.         (s1, ioState1)    = f s ioState;
  315.         (found, f)        = MenuSystemState_MenuFunction h v menus;
  316.     };
  317. MenuIO` AboutEvent menus s ioState
  318.     =    (True, s1, ioState1);
  319.     where {
  320.         (s1, ioState1) = OpenAboutDialog s ioState;
  321.     };
  322. MenuIO` DeskEvent menus s ioState
  323.     =     (True, s, ioState);
  324. MenuIO` noMenuEvent menus s ioState
  325.     =     (False, s, ioState);
  326.  
  327. MenuTrace :: !Event !(DeviceSystemState s) !Toolbox -> (!TraceResult, !Toolbox);
  328. MenuTrace    event        =:(b,MouseDownEvent,mess,i,h,v,mods)
  329.             menuSystem    =:(MenuSystemState (menus, cuts, handle, systemAble)) tb
  330. |    region == menuBar                = MenuSelection barMenuId barItemNr menus tb2;
  331. |    region == inSysWindow            = (NoMenuEvent, SystemClick (1,mess,i,h,v,mods) wPtr tb1);
  332.                                     = (NoMenuEvent, tb1);
  333.     where {
  334.         (region, wPtr, tb1)            = FindWindow h v tb;
  335.         (barMenuId, barItemNr, tb2)    = MenuSelect h v tb1;
  336.         inSysWindow                    = 2;
  337.         menuBar                        = 1;
  338.     };
  339. MenuTrace (b,KeyUpEvent,message,i,h,v,mods) menuSystem tb
  340. |    commandKeyUp                    = (NoMenuEvent,    tb);
  341. |    menuId <> 0                        = (DeskEvent,    tb2);
  342.                                     = (NoMenuEvent,    tb2);
  343.     where {
  344.         (menuId, menuItemNr, tb1)    = MenuKey charCode tb;
  345.         tb2                            = HiliteMenu 0 tb1;
  346.         charCode                    = message bitand 255;
  347.         commandKeyDown                = (mods bitand 256) <> 0;
  348.         commandKeyUp                = (mods bitand 256) == 0;
  349.     };
  350. MenuTrace    event        =:(b,what,message,i,h,v,mods)
  351.             menuSystem    =:(MenuSystemState (menus, cuts, handle, systemAble)) tb
  352. |    (what <> KeyDownEvent && what <> AutoKeyEvent)
  353. ||    commandKeyUp                    = (NoMenuEvent, tb);
  354. |    otherItem                        = MenuSelection menuId menuItemNr menus tb1;
  355.                                     = (NoMenuEvent, tb1);
  356.     where {
  357.         (menuId, menuItemNr, tb1)    = MenuKey charCode tb;
  358.         charCode                    = message bitand 255;
  359.         otherItem                    = menuId <> 0;
  360.         commandKeyUp                = (mods bitand 256) == 0;
  361.     };
  362.  
  363. MenuSelection :: !Int !Int ![MenuHandle s] !Toolbox -> (!TraceResult, !Toolbox);
  364. MenuSelection no_choice=:0 menuItem menuHs tb
  365.     =    (NoMenuEvent, HiliteMenu 0 tb);
  366. MenuSelection AppleMenuId menuItem menuHs tb
  367. |    menuItem >= 3    = (DeskEvent,  OpenAccessory menuHs menuItem tb1);
  368. |    menuItem == 1    = (AboutEvent, tb1);
  369.                     = (NoMenuEvent,tb1);
  370.     where {
  371.         tb1 = HiliteMenu 0 tb;
  372.     };
  373. MenuSelection menuId menuItem menuHs tb
  374.     =    (MenuEvent menuId menuItem, HiliteMenu 0 tb);
  375.  
  376.  
  377. //    Change the title of the Apple menu:
  378.  
  379. IOStateChangeAppleMenuTitle    :: !String !(IOState s) -> IOState s;
  380. IOStateChangeAppleMenuTitle applicationName ioState
  381.     =    IOStateSetToolbox (MenusChangeAppleMenuTitle applicationName menus tb) ioState2;
  382.     where {
  383.         (tb,    ioState2) = IOStateGetToolbox ioState1;
  384.         (menus,    ioState1) = IOStateGetDevice ioState MenuDevice;
  385.     };
  386.  
  387. MenusChangeAppleMenuTitle :: !String !(DeviceSystemState s) !Toolbox -> Toolbox;
  388. MenusChangeAppleMenuTitle name (MenuSystemState ([apple=:PullDownHandle menuH _ _ _ _ : _],_,_,_)) tb
  389.     =    SetItem menuH 1 ("About " +++ name +++ "...") tb;
  390.  
  391.  
  392. //    Providing an extra layer over desk:
  393.  
  394. OpenAccessory :: ![MenuHandle s] !Int !Toolbox -> Toolbox;
  395. OpenAccessory [PullDownHandle appleH id macId able items : m_and_hs] item tb
  396.     =    tb2;
  397.     where {
  398.         (acc, tb1)    = GetItem appleH item String256 tb;
  399.         tb2            = OpenDeskAcc acc tb1;
  400.     };
  401.  
  402. String256 :: String;
  403. String256
  404.     =    string128 +++ string128;
  405.     where {
  406.         string128 = "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@";
  407.     };
  408.